package com.sunyuechao.vhr.framework.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sunyuechao.vhr.framework.entity.Hr;
import com.sunyuechao.vhr.framework.entity.RespBean;
import com.sunyuechao.vhr.framework.service.IHrService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import java.security.Provider;

/**
 * Created by SunYuechao on 2024/1/29 下午1:40
 */
@Configuration
public class SecurityConfig {
    @Autowired
    IHrService hrService;
    /**
     * 过滤器链
     * @return
     */
    @Bean
    JsonFilter jsonFilter(){
        JsonFilter jsonFilter=new JsonFilter();
        jsonFilter.setFilterProcessesUrl("/login");
        jsonFilter.setAuthenticationSuccessHandler(
                (req,resp,auth)->{
                    resp.setContentType("application/json;charset=utf-8");
                    Hr principal = (Hr) auth.getPrincipal();
                    principal.setPassword(null);
                    resp.getWriter().write(new ObjectMapper().writeValueAsString(RespBean.ok("登录成功",principal)));
                }
        );
        jsonFilter.setAuthenticationFailureHandler(
                (req,resp,e)->{
                    resp.setContentType("application/json;charset=utf-8");
                    RespBean error = RespBean.error("登录失败");
                    if(e instanceof BadCredentialsException){
                        error.setMessages("密码或用户名错误，登录失败！");
                    }else if(e instanceof DisabledException){
                        error.setMessages("账号被禁用，登录失败！");
                    }
                    resp.getWriter().write(new ObjectMapper().writeValueAsString(error));
                }
        );
        //指定管理器
        jsonFilter.setAuthenticationManager(authenticationManager());
        //指定存储仓库
        jsonFilter.setSecurityContextRepository(new HttpSessionSecurityContextRepository());

        return jsonFilter;
    }

    @Bean
    AuthenticationManager authenticationManager(){
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(hrService);
        ProviderManager providerManager = new ProviderManager(daoAuthenticationProvider);
        return providerManager;
    }

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        /**
         * 拦截所以请求，但是不经过任何过滤器
         */
        //return new DefaultSecurityFilterChain(new AntPathRequestMatcher("/**"));
        //在默认的基础过滤链上写
        http.authorizeHttpRequests(p->p.anyRequest().authenticated())
                .formLogin(f->f.usernameParameter("username").passwordParameter("password").
                        loginProcessingUrl("/login").successHandler(
                                (req,resp,auth)->{
                                    resp.setContentType("application/json;charset=utf-8");
                                    Hr principal = (Hr) auth.getPrincipal();
                                    principal.setPassword(null);
                                    resp.getWriter().write(new ObjectMapper().writeValueAsString(RespBean.ok("登录成功",principal)));
                                }
                        ).failureHandler(
                                (req,resp,e)->{
                                    resp.setContentType("application/json;charset=utf-8");
                                    RespBean error = RespBean.error("登录失败");
                                    if(e instanceof BadCredentialsException){
                                        error.setMessages("密码或用户名错误，登录失败！");
                                    }else if(e instanceof DisabledException){
                                        error.setMessages("账号被禁用，登录失败！");
                                    }
                                    resp.getWriter().write(new ObjectMapper().writeValueAsString(error));
                                }
                        ))
                .csrf(c->c.disable())
                .exceptionHandling(e->e.authenticationEntryPoint((req,resp,ex)->{
                    resp.setContentType("application/json;charset=utf-8");
                    resp.setStatus(401);
                    RespBean error = RespBean.error("尚未登录，请先登录！");
                    resp.getWriter().write(new ObjectMapper().writeValueAsString(error));
                }));
        http.addFilterBefore(jsonFilter(), UsernamePasswordAuthenticationFilter.class);
       return http.build();

    }

}
